function BinHexDecodeStart (var bh: BinHexEncodeState; var name: Str63; var fi: FInfo; var dlen, rlen: longint; p: Ptr; len: longint; var count: longint): OSErr;
function BinHexDecodeChunk (var bh: BinHexEncodeState; inp: Ptr; inlen: longint; var inused: longint; outp: Ptr; outlen: longint; var outused: longint; var eofork, eofile: boolean): OSErr;
implementation
uses
Memory, CalcCRC, MyLowLevel, MyStartup;
const
binhex_start_string_hack = '(This file must be converted with BinHex 4.0)';
procedure BHGetByte (var bh: BinHexEncodeState; p: Ptr; len: longint; var count: longint; var err: OSErr; var n: integer);
procedure GB (var n: integer);
label
1;
var
b: integer;
begin
if err = noErr then begin
1:
while (count < len) & (AddPtrLong(p, count)^ < 32) do begin
count := count + 1;
end;
if count >= len then begin
err := notEnoughData;
end else begin
b := map[BAND(AddPtrLong(p, count)^, $FF)];
count := count + 1;
if b = dud_byte then begin
err := -3;
end else begin
case bh.state of
0: begin
bh.bits := b;
bh.state := 1;
goto 1;
end;
1: begin
n := BOR(BSL(bh.bits, 2), BAND(BSR(b, 4), $03));
bh.bits := b;
bh.state := 2;
end;
2: begin
n := BOR(BSL(bh.bits, 4), BAND(BSR(b, 2), $0F));
bh.bits := b;
bh.state := 3;
end;
3: begin
n := BOR(BSL(bh.bits, 6), BAND(b, $3F));
bh.state := 0;
end;
end;
n := BAND(n, $FF);
end;
end;
end;
end;
label
1;
var
c: integer;
oldstate: BinHexEncodeState;
oldcount: longint;
begin
1:
if err = noErr then begin
oldstate := bh;
oldcount := count;
if bh.repcnt > 0 then begin
n := bh.lastbyte;
bh.repcnt := bh.repcnt - 1;
end else begin
GB(n);
if (err = noErr) & (n = rep) then begin
GB(c);
if err = noErr then begin
case c of
0:
; { Do nothing, pass back the literal rep }
1:
goto 1; { Pretty damn stupid to have a rep count of 1 }
otherwise begin
n := bh.lastbyte;
bh.repcnt := c - 2;
end;
end;
end;
end;
end;
if err = notEnoughData then begin
bh := oldstate;
count := oldcount;
end else begin
CalcMBCRC(bh.crc, n);
bh.lastbyte := n;
end;
end;
end;
function BinHexDecodeStart (var bh: BinHexEncodeState; var name: Str63; var fi: FInfo; var dlen, rlen: longint; p: Ptr; len: longint; var count: longint): OSErr;
var
err: OSErr;
procedure GetByte (var n: integer);
begin
BHGetByte(bh, p, len, count, err, n);
end;
procedure GetInteger (var x: univ integer);
var
n, i: integer;
begin
x := 0;
for i := 1 to 2 do begin
GetByte(n);
x := BOR(BSL(x, 8), n);
end;
end;
procedure GetLong (var x: univ longint);
var
n, i: integer;
begin
x := 0;
for i := 1 to 4 do begin
GetByte(n);
x := BOR(BSL(x, 8), n);
end;
end;
var
namelen, n, i: integer;
thecrc, realcrc: integer;
begin
err := notEnoughData;
count := 0;
while count < len - binhex_check_length do begin
if AddPtrLong(p, count)^ = first_binhex_char then begin
if AddPtrLong(p, count + 1)^ = second_binhex_char then begin
i := 3;
while (i <= binhex_check_length) and (AddPtrLong(p, count + i - 1)^ = ord(binhex_start_string[i])) do begin
i := i + 1;
end;
if i > binhex_check_length then begin
err := noErr;
leave;
end;
end;
end;
count := count + 1;
end;
if err = noErr then begin
count := count + binhex_check_length;
while (count < len) & (AddPtrLong(p, count)^ >= 32) do begin
count := count + 1;
end;
while (count < len) & (AddPtrLong(p, count)^ <= 32) do begin
count := count + 1;
end;
if count >= len then begin
err := notEnoughData;
end else if (AddPtrLong(p, count)^ <> ord(':')) then begin
err := -73;
end else begin
count := count + 1;
end;
end;
if err = noErr then begin
bh.state := 0;
bh.repcnt := 0;
bh.crc := 0;
GetByte(namelen);
if (err = noErr) & ((namelen <= 0) | (namelen > 63)) then begin
err := -4;
end;
end;
if (err = noErr) then begin
name[0] := chr(namelen);
if (err = noErr) then begin
for i := 1 to namelen do begin
GetByte(n);
name[i] := chr(n);
end;
end;
GetByte(n);
if (err = noErr) & (n <> 0) then begin
err := -5;
end;
GetLong(fi.fdType);
GetLong(fi.fdCreator);
GetInteger(fi.fdFlags);
GetLong(dlen);
bh.dlen := dlen;
GetLong(rlen);
bh.rlen := rlen;
realcrc := bh.crc;
GetInteger(thecrc);
bh.crc := 0;
bh.datafork := true;
if (err = noErr) & ((dlen < 0) | (dlen > $10000000) | (rlen < 0) | (rlen > $10000000) | (thecrc <> realcrc)) then begin
err := -6;
end;
end;
BinHexDecodeStart := err;
end;
function BinHexDecodeChunk (var bh: BinHexEncodeState; inp: Ptr; inlen: longint; var inused: longint; outp: Ptr; outlen: longint; var outused: longint; var eofork, eofile: boolean): OSErr;
var
err: OSErr;
n, h, l: integer;
oldinused: longint;
oldstate: BinHexEncodeState;
realcrc, thecrc: integer;
begin
err := noErr;
inused := 0;
outused := 0;
eofork := false;
eofile := false;
while (err = noErr) & (bh.dlen > 0) & (outused < outlen) do begin